#include "physicscompwidget.h"

PhysicsCompWidget::PhysicsCompWidget(AED_PhysicsComp *comp, QWidget *parent) :
    QWidget(parent)
{


    //this->setMaximumHeight(200);
    QVBoxLayout *layout = new QVBoxLayout;
    this->setLayout(layout);

    group = new QGroupBox("Enable");
    layout->addWidget(group);
    group->setCheckable(true);




    QVBoxLayout *main_layout = new QVBoxLayout; // La layout principal
    group->setLayout(main_layout);


    friction = new QDoubleSpinBox();
    restitution = new QDoubleSpinBox();
    sensor = new QCheckBox("Sensor");
    shape = new QComboBox;
    shape->addItem("circle");
    shape->addItem("box");
    shape->addItem("polygon");
    shape_size_x = new QDoubleSpinBox();
    shape_size_y = new QDoubleSpinBox();
    linear_damping = new QDoubleSpinBox();
    angular_damping = new QDoubleSpinBox();
    density = new QDoubleSpinBox();
    type = new QComboBox;
    type->addItem("static");
    type->addItem("dynamic");
    fixed_rotation = new QCheckBox("Fixed Rotation");
    bullet = new QCheckBox("Bullet");


    QLabel *friction_l = new QLabel("Friction");
    QLabel *restitution_l = new QLabel("Restitution");
    QLabel *density_l = new QLabel("Density");
    QLabel *shape_l = new QLabel("Collision Shape");
    QLabel *shape_size_l_x = new QLabel("Shape Size X");
    QLabel *shape_size_l_y = new QLabel("Shape Size Y");
    QLabel *linear_damping_l = new QLabel("Linear Damping");
    QLabel *angular_damping_l = new QLabel("Angular Damping");
    QLabel *type_l = new QLabel("Body Type");
    points_l = new QLabel("Polygon Shape Points (Counter Clockwise!):");

    QHBoxLayout *hbox1 = new QHBoxLayout;
    QHBoxLayout *hbox2 = new QHBoxLayout;
    QHBoxLayout *hbox3 = new QHBoxLayout;
    QHBoxLayout *hbox4 = new QHBoxLayout;
    QHBoxLayout *hbox5 = new QHBoxLayout;
    QHBoxLayout *hbox6 = new QHBoxLayout;
    QHBoxLayout *hbox7 = new QHBoxLayout;
    QHBoxLayout *hbox8 = new QHBoxLayout;
    QHBoxLayout *hbox9 = new QHBoxLayout;
    QHBoxLayout *hbox10 = new QHBoxLayout;
    QHBoxLayout *hbox11 = new QHBoxLayout;
    QHBoxLayout *hbox12 = new QHBoxLayout;
    QHBoxLayout *hbox13 = new QHBoxLayout;
    QHBoxLayout *hbox14 = new QHBoxLayout;

    hbox1->addWidget(friction_l);
    hbox1->addWidget(friction);
    hbox12->addWidget(restitution_l);
    hbox12->addWidget(restitution);
    hbox3->addWidget(linear_damping_l);
    hbox3->addWidget(linear_damping);
    hbox13->addWidget(angular_damping_l);
    hbox13->addWidget(angular_damping);
    hbox5->addWidget(type_l);
    hbox5->addWidget(type);
    hbox11->addWidget(shape_l);
    hbox11->addWidget(shape);
    hbox6->addWidget(density_l);
    hbox6->addWidget(density);
    hbox14->addWidget(shape_size_l_x);
    hbox14->addWidget(shape_size_x);
    hbox14->addWidget(shape_size_l_y);
    hbox14->addWidget(shape_size_y);
    addpoint = new QPushButton("Add Point");
    removepoint = new QPushButton("Remove Point");
    hbox8->addWidget(addpoint);
    hbox8->addWidget(removepoint);
    addcond  = new QPushButton("Add Condition");
    removecond  = new QPushButton("Remove Condition");
    hbox9->addWidget(addcond);
    hbox9->addWidget(removecond);

    hbox10->addWidget(sensor);
    hbox10->addWidget(bullet);
    hbox10->addWidget(fixed_rotation);
    m_model = 0;
    m_pointtable = new QTableView();


    m_pointtable->setSelectionBehavior(QAbstractItemView::SelectRows);
    m_pointtable->horizontalHeader()->setResizeMode(QHeaderView::Stretch);
    //m_pointtable->resizeColumnsToContents();

    m_cmodel = 0;
    m_condtable = new QTableView();

    m_condtable->setSelectionBehavior(QAbstractItemView::SelectRows);
    m_condtable->resizeColumnsToContents();
    m_condtable->horizontalHeader()->setResizeMode(QHeaderView::Stretch);


    main_layout->addLayout(hbox5);
    main_layout->addLayout(hbox10);
    main_layout->addLayout(hbox1);
    main_layout->addLayout(hbox12);
    main_layout->addLayout(hbox2);
    main_layout->addLayout(hbox3);
    main_layout->addLayout(hbox13);
    main_layout->addLayout(hbox4);
    main_layout->addLayout(hbox6);
    main_layout->addLayout(hbox14);
    main_layout->addLayout(hbox11);
    main_layout->addLayout(hbox7);
    main_layout->addWidget(points_l);
    main_layout->addLayout(hbox8);
    main_layout->addWidget(m_pointtable);
    main_layout->addWidget(new QLabel("Conditions:"));
    main_layout->addLayout(hbox9);
    main_layout->addWidget(m_condtable);


    connect(group, SIGNAL(toggled(bool)),
                this,SLOT(SetEnabled(bool)));

    connect(friction, SIGNAL(valueChanged(double)),
                this, SLOT(SetFriction(double)));
    connect(restitution, SIGNAL(valueChanged(double)),
                this, SLOT(SetRestitution(double)));
    connect(sensor, SIGNAL(toggled(bool)),
                this, SLOT(SetSensor(bool)));
    connect(bullet, SIGNAL(toggled(bool)),
                this, SLOT(SetBullet(bool)));
    connect(fixed_rotation, SIGNAL(toggled(bool)),
             this, SLOT(SetFixedRotation(bool)));
    connect(linear_damping, SIGNAL(valueChanged(double)),
                this, SLOT(SetLinearDamping(double)));
    connect(angular_damping, SIGNAL(valueChanged(double)),
                this, SLOT(SetAngularDamping(double)));
    connect(density, SIGNAL(valueChanged(double)),
                this, SLOT(SetDensity(double)));
    connect(shape_size_x, SIGNAL(valueChanged(double)),
                this, SLOT(SetShapeSizeX(double)));
    connect(shape_size_y, SIGNAL(valueChanged(double)),
                this, SLOT(SetShapeSizeY(double)));
    connect(shape, SIGNAL(activated(QString)),
                this, SLOT(SetShape(QString)));
    connect(type, SIGNAL(activated(QString)),
                this, SLOT(SetType(QString)));

    connect(removepoint, SIGNAL(pressed()),
                this, SLOT(RemovePoint()));

    connect(removecond, SIGNAL(pressed()),
                this, SLOT(RemoveCondition()));

    setComp(comp);

}


void PhysicsCompWidget::setComp(AED_PhysicsComp *comp){
    m_comp = comp;
    if(!m_comp){
        group->setEnabled(false);
        //shape_size_y->setDisabled(true);
    }else{
        disconnect(addpoint);
        disconnect(addcond);
        group->setEnabled(true);
        group->setChecked(comp->IsEnabled());
        friction->setValue(m_comp->GetFriction());
        restitution->setValue(m_comp->GetRestitution());
        sensor->setChecked(m_comp->GetSensor());

        QString shp = m_comp->GetShape();
        int shand = shape->findText(shp);
        shape->setCurrentIndex(shand);

        if(shp=="polygon"){

            m_pointtable->setDisabled(false);
            addpoint->setDisabled(false);
            removepoint->setDisabled(false);
            points_l->setDisabled(false);
        }else{
            m_pointtable->setDisabled(true);
            addpoint->setDisabled(true);
            removepoint->setDisabled(true);
            points_l->setDisabled(true);
        }

        /*if(shp == "circle"){
            shape_size_y->setDisabled(true);
        }else{
            shape_size_y->setDisabled(false);
        }*/


        shape_size_x->setValue(m_comp->GetShapeSizeX());
        shape_size_y->setValue(m_comp->GetShapeSizeY());
        linear_damping->setValue(m_comp->GetLinearDamping());
        angular_damping->setValue(m_comp->GetAngularDamping());
        density->setValue(m_comp->GetDensity());

        QString st = m_comp->GetType();
        int shind = type->findText(st);
        type->setCurrentIndex(shind);

        fixed_rotation->setChecked(m_comp->GetFixedRotation());
        bullet->setChecked(m_comp->GetBullet());

        if(m_model)
            delete m_model;
        m_model = new PolygonPointsModel(m_comp);
        m_pointtable->setModel(m_model);

        if(m_cmodel)
            delete m_cmodel;
        m_cmodel = new PhysicsCondModel(m_comp);
        m_condtable->setModel(m_cmodel);

        connect(addpoint, SIGNAL(pressed()),
                    m_model, SLOT(AddPoint()));

        connect(addcond, SIGNAL(pressed()),
                m_cmodel, SLOT(AddCondition()));
    }

}


void PhysicsCompWidget::RemovePoint(){
    QModelIndexList lstIndex ;

    QItemSelection ranges = m_pointtable->selectionModel()->selection();
    for (int i = 0; i < ranges.count(); ++i){
        QModelIndex parent = ranges.at(i).parent();
        int right = ranges.at(i).model()->columnCount(parent) - 1;
        if (ranges.at(i).left() == 0 && ranges.at(i).right() == right)
            for (int r = ranges.at(i).top(); r <= ranges.at(i).bottom(); ++r)
                lstIndex.append(ranges.at(i).model()->index(r, 0, parent));
    }
    for(int i=0; i<lstIndex.size();i++){
        QModelIndex index = lstIndex.at(i);
        if(index.isValid()){
            m_model->RemovePoint(index.row());
        }
    }
}

void PhysicsCompWidget::RemoveCondition(){
    QModelIndexList lstIndex ;

    QItemSelection ranges = m_condtable->selectionModel()->selection();
    for (int i = 0; i < ranges.count(); ++i){
        QModelIndex parent = ranges.at(i).parent();
        int right = ranges.at(i).model()->columnCount(parent) - 1;
        if (ranges.at(i).left() == 0 && ranges.at(i).right() == right)
            for (int r = ranges.at(i).top(); r <= ranges.at(i).bottom(); ++r)
                lstIndex.append(ranges.at(i).model()->index(r, 0, parent));
    }
    for(int i=0; i<lstIndex.size();i++){
        QModelIndex index = lstIndex.at(i);
        if(index.isValid()){
            m_cmodel->RemoveCondition(index.row());
        }
    }
}

